import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
import { computed, defineComponent, PropType, VNode } from 'vue';
import {
  IDEDataView,
  ILayoutPanel,
  IUIActionGroupDetail,
} from '@ibiz/model-core';
import {
  DataViewControlController,
  IControlProvider,
  IMDControlGroupState,
  ISortItem,
} from '@ibiz-template/runtime';
import './data-view.scss';
import { usePagination } from '../../util';

export const DataViewControl = defineComponent({
  name: 'IBizDataViewControl',
  props: {
    modelData: { type: Object as PropType<IDEDataView>, required: true },
    context: { type: Object as PropType<IContext>, required: true },
    params: { type: Object as PropType<IParams>, default: () => ({}) },
    provider: { type: Object as PropType<IControlProvider> },
    /**
     * 部件行数据默认激活模式
     * - 0 不激活
     * - 1 单击激活
     * - 2 双击激活(默认值)
     *
     * @type {(number | 0 | 1 | 2)}
     */
    mdctrlActiveMode: { type: Number, default: undefined },
    singleSelect: { type: Boolean, default: undefined },
    loadDefault: { type: Boolean, default: true },
  },
  setup(props) {
    const c = useControlController(
      (...args) => new DataViewControlController<IDEDataView>(...args),
    );
    const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`);

    const classNames = computed(() => {
      return [ns.is('enable-page', c.model.enablePagingBar === true)];
    });

    // 是否可以加载更多
    const isLodeMoreDisabled = computed(() => {
      if (c.model.enablePagingBar === true) {
        return true;
      }
      return (
        c.state.items.length >= c.state.total ||
        c.state.isLoading ||
        c.state.total <= c.state.size
      );
    });

    const { onPageChange, onPageRefresh, onPageSizeChange } = usePagination(c);

    // 行单击事件
    const onRowClick = (item: IData, event: MouseEvent): Promise<void> => {
      event.stopPropagation();
      return c.onRowClick(item);
    };

    // 行双击事件
    const onDbRowClick = (item: IData, event: MouseEvent): Promise<void> => {
      event.stopPropagation();
      return c.onDbRowClick(item);
    };

    // 绘制项布局面板
    const renderPanelItem = (item: IData, modelData: ILayoutPanel): VNode => {
      const { context, params } = c;
      return (
        <iBizControlShell
          data={item}
          modelData={modelData}
          context={context}
          params={params}
          onClick={(event: MouseEvent): Promise<void> =>
            onRowClick(item, event)
          }
          onDblclick={(event: MouseEvent): Promise<void> =>
            onDbRowClick(item, event)
          }
        ></iBizControlShell>
      );
    };
    // 绘制项行为
    const renderItemAction = (item: IData): VNode => {
      return (
        <iBizActionToolbar
          class={ns.bem('item-content', 'bottom', 'actions')}
          action-details={
            c.getOptItemModel()!.deuiactionGroup?.uiactionGroupDetails
          }
          actions-state={c.getOptItemAction(item)}
          onActionClick={(
            detail: IUIActionGroupDetail,
            event: MouseEvent,
          ): Promise<void> => c.onActionClick(detail, item, event)}
        ></iBizActionToolbar>
      );
    };

    // 绘制默认项
    const renderDefaultItem = (item: IData): VNode => {
      return (
        <div class={ns.b('item-content')}>
          <div class={ns.be('item-content', 'top')}>
            <div class={ns.bem('item-content', 'top', 'title')}>
              {item.srfmajortext}
            </div>
            <div class={ns.bem('item-content', 'top', 'description')}>
              {item.content}
            </div>
          </div>
          {c.getOptItemModel() ? (
            <div class={ns.be('item-content', 'bottom')}>
              {renderItemAction(item)}
            </div>
          ) : null}
        </div>
      );
    };

    // 绘制卡片
    const renderCard = (item: IData): VNode => {
      // 是否选中数据
      const findIndex = c.state.selectedData.findIndex(data => {
        return data.srfkey === item.srfkey;
      });
      let showActive = findIndex !== -1;
      if (
        c.view.model.viewType === 'DEDATAVIEW' &&
        c.state.mdctrlActiveMode === 1 &&
        c.state.singleSelect === true
      ) {
        showActive = false;
      }
      const cardClass = [ns.b('item'), ns.is('active', showActive)];
      const cardStyle = {};
      if (c.model.cardWidth) {
        Object.assign(cardStyle, {
          width: `${c.model.cardWidth}px`,
        });
      }
      if (c.model.cardHeight) {
        Object.assign(cardStyle, {
          height: `${c.model.cardHeight}px`,
        });
      }
      const panel = props.modelData.itemLayoutPanel;

      return (
        <el-card
          shadow='hover'
          class={cardClass}
          body-style={cardStyle}
          onClick={(event: MouseEvent): Promise<void> =>
            onRowClick(item, event)
          }
          onDblclick={(event: MouseEvent): Promise<void> =>
            onDbRowClick(item, event)
          }
        >
          {panel ? renderPanelItem(item, panel) : renderDefaultItem(item)}
        </el-card>
      );
    };

    // 绘制分组
    const renderGroup = (group: IMDControlGroupState): VNode => {
      const { cardColXS, cardColSM, cardColMD, cardColLG, groupSysCss } =
        c.model;
      return (
        <div class={[ns.be('group-content', 'item'), groupSysCss?.cssName]}>
          <div class={ns.be('group-content', 'item-header')}>
            <span class={ns.be('group-content', 'item-title')}>
              {group.caption}
            </span>
            <span class={ns.be('group-content', 'item-action')}>
              {c.model.groupUIActionGroup && group.groupActionGroupState && (
                <iBizActionToolbar
                  class={ns.be('group-content', 'header-actions')}
                  action-details={
                    c.model.groupUIActionGroup.uiactionGroupDetails
                  }
                  actions-state={group.groupActionGroupState}
                  onActionClick={(
                    detail: IUIActionGroupDetail,
                    event: MouseEvent,
                  ) => {
                    c.onGroupToolbarClick(detail, event, group);
                  }}
                ></iBizActionToolbar>
              )}
            </span>
          </div>
          {cardColXS || cardColSM || cardColMD || cardColLG ? (
            <el-row class={ns.be('group-content', 'item-row')}>
              {group.children.length > 0 ? (
                group.children.map(child => {
                  return (
                    <el-col
                      xs={cardColXS}
                      sm={cardColSM}
                      md={cardColMD}
                      lg={cardColLG}
                      class={ns.be('group-content', 'item-col')}
                    >
                      {renderCard(child)}
                    </el-col>
                  );
                })
              ) : (
                <div class={ns.bem('group-content', 'item', 'empty')}>
                  {ibiz.i18n.t('app.noData')}
                </div>
              )}
            </el-row>
          ) : (
            <div class={ns.be('group-content', 'item-content')}>
              {group.children.length > 0 ? (
                group.children.map(child => {
                  return renderCard(child);
                })
              ) : (
                <div class={ns.bem('group-content', 'item', 'empty')}>
                  {ibiz.i18n.t('app.noData')}
                </div>
              )}
            </div>
          )}
        </div>
      );
    };

    // 绘制卡片内容
    const renderDataViewContent = (): VNode | VNode[] => {
      const { cardColXS, cardColSM, cardColMD, cardColLG } = c.model;
      if (c.model.enableGroup) {
        return (
          <div class={ns.b('group-content')}>
            {c.state.groups.map(group => {
              return (
                <div class={[ns.b('scroll-item')]}>{renderGroup(group)}</div>
              );
            })}
          </div>
        );
      }
      if (cardColXS || cardColSM || cardColMD || cardColLG) {
        return (
          <el-row class={[ns.b('item-row')]}>
            {c.state.items.map(item => {
              return (
                <el-col
                  xs={cardColXS}
                  sm={cardColSM}
                  md={cardColMD}
                  lg={cardColLG}
                  class={[ns.b('item-col')]}
                >
                  {renderCard(item)}
                </el-col>
              );
            })}
          </el-row>
        );
      }
      return c.state.items.map(item => {
        return <div class={[ns.b('scroll-item')]}>{renderCard(item)}</div>;
      });
    };

    // 绘制有数据的时候的呈现
    const renderHasData = (): VNode => {
      return (
        <div
          class={[ns.b('scroll'), ns.e('content')]}
          v-infinite-scroll={(): Promise<void> => c.loadMore()}
          infinite-scroll-distance={10}
          infinite-scroll-disabled={isLodeMoreDisabled.value}
        >
          {renderDataViewContent()}
        </div>
      );
    };

    const renderNoData = (): VNode | undefined => {
      // 未加载不显示无数据
      const { isLoaded } = c.state;
      if (!isLoaded) {
        return;
      }
      return (
        <iBizNoData
          class={ns.e('content')}
          text={c.model.emptyText}
          emptyTextLanguageRes={c.model.emptyTextLanguageRes}
        ></iBizNoData>
      );
    };

    return {
      c,
      ns,
      classNames,
      renderHasData,
      renderNoData,
      onPageChange,
      onPageRefresh,
      onPageSizeChange,
    };
  },
  render() {
    const { items, isCreated } = this.c.state;
    const { enablePagingBar } = this.c.model;

    let content = null;
    if (isCreated) {
      content = [
        this.c.state.noSort ? null : (
          <iBizSortBar
            onSortChange={(item: ISortItem, order: 'asc' | 'desc') => {
              this.c.setSort(item.key, order);
              this.c.load();
            }}
            sortItems={this.c.state.sortItems}
          ></iBizSortBar>
        ),
        items.length > 0 ? this.renderHasData() : this.renderNoData(),
        enablePagingBar ? (
          <iBizPagination
            class={this.ns.e('pagination')}
            total={this.c.state.total}
            curPage={this.c.state.curPage}
            size={this.c.state.size}
            totalPages={this.c.state.totalPages}
            onChange={this.onPageChange}
            onPageSizeChange={this.onPageSizeChange}
            onPageRefresh={this.onPageRefresh}
          ></iBizPagination>
        ) : null,
      ];
    }

    return (
      <iBizControlBase
        class={[this.ns.is('enable-page', !!enablePagingBar)]}
        controller={this.c}
      >
        {content}
      </iBizControlBase>
    );
  },
});
